package lab.bmp.genre;

import java.rmi.RemoteException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.EntityContext;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import lab.bmp.NamedRecordBean;
import lab.bmp.track.TrackPK;
import lab.domain.Genre;
import lab.logging.LoggingUtil;
import ru.ssau.DatabaseHelper;

/**
 *
 * @author Smike
 */
public class GenreBean implements NamedRecordBean<GenrePK> {

    EntityContext context;
    DataSource datasource;
    lab.domain.Genre genre;
    boolean changed;

    public void setEntityContext(EntityContext ctx) throws EJBException, RemoteException {
        this.context = ctx;
    }

    public void unsetEntityContext() throws EJBException, RemoteException {
        this.context = null;
    }

    public void ejbRemove() throws RemoveException, EJBException, RemoteException {
        GenrePK key = getCurrentKey();
        lab.domain.Genre genre = new lab.domain.Genre();
        genre.setId(key.getId());
        Connection connection = getConnection();
        try {
            DatabaseHelper.deleteGenre(connection, genre);
        } catch (SQLException ex) {
            throw new RemoveException(ex.getMessage());
        } finally {
            try {
                connection.close();
            } catch (Exception e) {
                // do nothing
            }
        }
    }

    public void ejbActivate() throws EJBException, RemoteException {
        // do nothing
    }

    public void ejbPassivate() throws EJBException, RemoteException {
    }

    public void ejbLoad() throws EJBException, RemoteException {
        changed = false;
        // do nothing, it is lazy
    }

    private void initializeIfNeeded() {
        if (genre == null) {
            GenrePK key = getCurrentKey();
            Connection connection = getConnection();
            try {
                this.genre = DatabaseHelper.findGenre(connection, key.getId());
            } catch (SQLException ex) {
                throw new EJBException(ex);
            } finally {
                try {
                    connection.close();
                } catch (Exception e) {
                    // do nothing
                }
            }
        }
    }

    public void ejbStore() throws EJBException, RemoteException {
        if (genre != null && changed) {
            Connection connection = getConnection();
            try {
                DatabaseHelper.updateGenre(connection, genre);
                LoggingUtil.log(LoggingUtil.GENRE);
            } catch (SQLException ex) {
                throw new EJBException(ex);
            } finally {
                try {
                    connection.close();
                } catch (Exception e) {
                    // do nothing
                }
            }
        }
    }

    GenrePK getCurrentKey() {
        return (GenrePK) context.getPrimaryKey();
    }

    public String getName() {
        initializeIfNeeded();
        return genre.getName();
    }

    public void setName(String name) {
        initializeIfNeeded();
        genre.setName(name);
        changed = true;
    }

    public Integer getId() {
        return getCurrentKey().getId();
    }

    public void setId(Integer id) {
        initializeIfNeeded();
        genre.setId(id);
        changed = true;
    }

    public GenrePK ejbCreate(Integer id, String name) throws CreateException {
        lab.domain.Genre genre = new lab.domain.Genre();
        genre.setName(name);
        Connection connection = getConnection();
        try {
            return new GenrePK(DatabaseHelper.insertGenre(connection, genre));
        } catch (SQLException ex) {
            throw new EJBException(ex);
        } finally {
            try {
                connection.close();
            } catch (Exception e) {
                // do nothing
            }
        }
    }

    public GenrePK ejbFindByPrimaryKey(GenrePK key) throws FinderException {
        lab.domain.Genre genre;
        Connection connection = getConnection();
        try {
            genre = DatabaseHelper.findGenre(connection, key.getId());
            return key;
        } catch (SQLException ex) {
            throw new FinderException(ex.getMessage());
        } finally {
            try {
                connection.close();
            } catch (Exception e) {
                // do nothing
            }
        }
    }

    public Collection ejbFindAll() throws FinderException {
        Connection connection = getConnection();
        try {
            Collection<lab.domain.Genre> genres = DatabaseHelper.findGenres(connection);
            Collection<GenrePK> keys = new ArrayList<GenrePK>();
            for (lab.domain.Genre genre : genres) {
                keys.add(new GenrePK(genre.getId()));
            }
            return keys;
        } catch (SQLException ex) {
            throw new FinderException(ex.getMessage());
        } finally {
            try {
                connection.close();
            } catch (Exception e) {
                // do nothing
            }
        }
    }

    public Collection ejbFindByTrack(TrackPK key) throws FinderException {
        Connection connection = getConnection();
        try {
            Collection<lab.domain.Genre> genres = DatabaseHelper.findTrackGenres(connection, key.getId());
            Collection<GenrePK> keys = new ArrayList<GenrePK>();
            for (lab.domain.Genre g : genres) {
                keys.add(new GenrePK(g.getId()));
            }
            return keys;
        } catch (SQLException ex) {
            throw new FinderException(ex.getMessage());
        } finally {
            try {
                connection.close();
            } catch (Exception e) {
                // do nothing
            }
        }
    }

    Connection getConnection() {
        try {
            return getDataSource().getConnection();
        } catch (SQLException ex) {
            throw new RuntimeException(ex);
        }
    }

    DataSource getDataSource() {
        try {
            return (DataSource) new InitialContext().lookup("oracleDS");
        } catch (NamingException ex) {
            throw new RuntimeException(ex);
        }
    }
}
